package hehe.router.easy;

import hehe.router.Controller;
import hehe.router.RequestUrl;
import hehe.router.Router;
import hehe.router.easy.rule.PathinfoRule;
import hehe.router.easy.rule.PatternRule;
import hehe.router.easy.rule.Rule;
import hehe.router.util.RouteHelper;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 简单易用路由规则
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class Easy extends Router
{

    /**
     *　自定义http 方法
     *<B>说明：</B>
     *<pre>
     *  未定义http 方法时,http方法默认为HEHE
     *</pre>
     */
    private static final String METHOD_HEHE = "HEHE";


    /**
     * 自定义验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected Map<String,List<Rule>> ruleList = new LinkedHashMap<>();

    public Easy() {}

    public Easy(Map<String,Object> attrs) {}

    public void addRule(Map<String,String> rule)
    {
        String pathinfoRule = "",urlRule = "",method = METHOD_HEHE;

        if (rule.containsKey("pathinfoRule")) {
            pathinfoRule = rule.get("pathinfoRule");
        }

        if (rule.containsKey("urlRule")) {
            urlRule = rule.get("urlRule");
        }

        if (rule.containsKey("method")) {
            method = rule.get("method");
        }

        this.addRule(pathinfoRule,urlRule,method);
    }

    /**
     * 添加路由规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param pathinfoRule pathinfo规则
     * @param urlRule url规则
     * @param method http方法
     */
    public void addRule(String pathinfoRule,String urlRule,String method)
    {

        Map<String,Object> ruleAttr = new HashMap<String,Object>(){{
            put("pathinfoRule",pathinfoRule);
            put("urlRule",urlRule);
        }};

        PatternRule patternRule = new PatternRule(ruleAttr);

        if (this.ruleList.containsKey(method)) {
            this.ruleList.get(method).add(patternRule);
        } else {
            List<Rule> rules = new ArrayList<>();
            rules.add(patternRule);
            this.ruleList.put(method,rules);
        }
    }

    /**
     * 匹配路由规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param pathInfo HttpServletRequest pathInfo
     * @param method Http 方法
     * @return  Controller 控制器
     */
    protected Controller executeRequestRules(String pathInfo,String method)
    {
        List<Rule> rules = this.getRules(method);
        if (rules == null || rules.size() == 0) {
            return null;
        }

        pathInfo = RouteHelper.trim(pathInfo,PatternRule.REG_SPLIT);
        Rule rule;
        Controller controller = null;

        // 匹配自定义路由规则
        for (int i = 0,j = rules.size(); i < j;i++) {
            rule = rules.get(i);
            controller = rule.parseRequest(pathInfo);
            if (controller != null) {
                break;
            }
        }

        return controller;
    }

    /**
     * 获取对应的路由规则
     *<B>说明：</B>
     *<pre>
     *  根据request　method　获取路由规则
     *</pre>
     */
    protected List<Rule> getRules(String method)
    {
        return this.ruleList.get(method);
    }

    /**
     * 查找控制器
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param pathInfo HttpServletRequest pathInfo
     * @return  Controller 控制器
     */
    public Controller findController(String pathInfo,String method)
    {
        // 读取当前request method
        Controller controller;

        controller = this.executeRequestRules(pathInfo,METHOD_HEHE);
        if (controller != null) {
            return controller;
        }

        controller = this.executeRequestRules(pathInfo,method);

        // 自定义规则未匹配,启用默认规则
        if (controller == null) {
            controller = new PathinfoRule().parseRequest(pathInfo);
        }

        return controller;
    }

    /**
     * 创建url 地址
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public RequestUrl createUrl(String url,Map<String,String> params,String method)
    {
        // 读取当前request method
        RequestUrl requestUrl;

        requestUrl = this.executeUrLRules(url,params,METHOD_HEHE);
        if (requestUrl != null) {
            return requestUrl;
        }

        requestUrl = this.executeUrLRules(url,params,method);

        // 自定义规则未匹配,启用默认规则
        if (requestUrl == null) {
            requestUrl = new PathinfoRule().parseUrL(url,params);
        }

        return requestUrl;
    }

    public RequestUrl executeUrLRules(String url,Map<String,String> params,String method)
    {
        List<Rule> rules = this.getRules(method);
        if (rules == null || rules.size() == 0) {
            return null;
        }

        Rule rule;
        RequestUrl requestUrl = null;

        // 匹配自定义路由规则
        for (int i = 0,j = rules.size(); i < j;i++) {
            rule = rules.get(i);
            requestUrl = rule.parseUrL(url,params);
            if (requestUrl != null) {
                break;
            }
        }

        return requestUrl;
    }
}
